package com.mcxx.modules.miniSalvation.fundpay.service.read;

import com.mcxx.common.exception.BizException;
import com.mcxx.modules.miniSalvation.fundpay.dto.SingleRollDTO;
import com.mcxx.modules.miniSalvation.fundpay.entity.SingleFundPayMemberEntity;
import com.mcxx.modules.miniSalvation.fundpay.service.write.SingleFundPayExceptionWriteService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.SingleFundPayWriteService;
import com.mcxx.util.Constant;
import com.yinhai.ta404.core.service.BaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service("singleCommonService")
public class SingleCommonService extends BaseService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SingleCommonService.class);

    @Autowired
    private SingleFundPayExceptionWriteService singleFundPayExceptionWriteService;
    @Autowired
    private SingleFundPayWriteService singleFundPayWriteService;


    public void handleRollDetailData(SingleRollDTO singleRollDTO, List<SingleFundPayMemberEntity> rollMembers) {
        Double sumFundNumber0 = rollMembers.stream().mapToDouble(SingleFundPayMemberEntity::getFundNumber).sum();

        List<SingleFundPayMemberEntity> results = new ArrayList<>();
        Map<String, List<SingleFundPayMemberEntity>> listMap = rollMembers.stream().collect(Collectors.groupingBy(SingleFundPayMemberEntity::getFamilyId));
        Set<String> familyIds = listMap.keySet();
//        if (singleRollDTO.getFundType().equals(Constant.FundType.ALLOWANCE_FUND_PAY)) {




            dealWithStandRollData(singleRollDTO, results, listMap);

        LOGGER.info("数据处理完毕，共生成数据{}条", results.size());


        singleFundPayExceptionWriteService.checkSaveFundPayException(singleRollDTO.getId(), singleRollDTO.getPayDate(), results);
        LOGGER.info("银行卡信息完整性检测完毕");


        singleFundPayWriteService.saveMemberPayRollInfo(results);
        LOGGER.info("成员一卡通发放名册详细数据保存完毕");


        Double sumFundNumber = results.stream().mapToDouble(SingleFundPayMemberEntity::getFundNumber).sum();
        System.out.println("汇总前金额：" + sumFundNumber0 + ";汇总后金额：" + sumFundNumber);
        singleFundPayWriteService.updatePayRollInfo(Constant.FundPayState.CREATE, familyIds.size(), results.size(), sumFundNumber, singleRollDTO.getId());
    }


    private void dealWithStandRollData(SingleRollDTO singleRollDTO,
                                       List<SingleFundPayMemberEntity> results,
                                       Map<String, List<SingleFundPayMemberEntity>> listMap) {

        LOGGER.info("开始处理数据：整户保取户主信息数据汇总，单人保取在保人员信息");
        Set<String> familyIds = listMap.keySet();
        LOGGER.info("当前名册家庭数共{}",familyIds.size());
        Iterator<String> it = familyIds.iterator();
        while (it.hasNext()) {
            String key = it.next();
            List<SingleFundPayMemberEntity> saveFamilyMembers = listMap.get(key);
            if (null == saveFamilyMembers || saveFamilyMembers.size() == 0)
                throw new BizException("-1", key + ":该家庭没有成员信息！");
            int members = saveFamilyMembers.get(0).getMembers();
            int saveMembers = saveFamilyMembers.get(0).getSaveMembers();

            if (members == saveMembers) {

                List<SingleFundPayMemberEntity> master = saveFamilyMembers.stream()
                        .filter(o -> o.getIsMaster() == 1).collect(Collectors.toList());
                if (master.size() > 1)
                    throw new BizException("-1",saveFamilyMembers.get(0).getFamilyId() + ":该家庭户主信息有误！");
                if (master.size() == 0) {
                    throw new BizException("-1",saveFamilyMembers.get(0).getFamilyId() + ":该家庭未查到户主信息，请先处理该业务数据！");
                }
                SingleFundPayMemberEntity sfme = new SingleFundPayMemberEntity();
                BeanUtils.copyProperties(master.get(0), sfme);
                sfme.setId(Constant.getUUID());

                Double sumFundNumber = saveFamilyMembers.stream().mapToDouble(SingleFundPayMemberEntity::getFundNumber).sum();
                sfme.setFundNumber(sumFundNumber);
                sfme.setFundPayId(singleRollDTO.getId());
                sfme.setPersonNumber(saveMembers);
                results.add(sfme);
            } else {

                for (SingleFundPayMemberEntity sfme : saveFamilyMembers) {
                    SingleFundPayMemberEntity sfm = new SingleFundPayMemberEntity();
                    BeanUtils.copyProperties(sfme, sfm);
                    sfm.setId(Constant.getUUID());
                    sfm.setFundPayId(singleRollDTO.getId());
                    results.add(sfm);
                }
            }
        }
    }


    private void dealWithAllowanceRollData(SingleRollDTO singleRollDTO,
                                           List<SingleFundPayMemberEntity> results,
                                           Map<String, List<SingleFundPayMemberEntity>> listMap) {
        String payId = singleRollDTO.getId();
        Set<String> familyIds = listMap.keySet();
        Iterator<String> it = familyIds.iterator();
        while (it.hasNext()) {
            String key = it.next();
            SingleFundPayMemberEntity lastMember = new SingleFundPayMemberEntity();

            getLastRollMember(key, listMap, lastMember);
            if (singleRollDTO.getGrantObject().equals(Constant.FundAllowanceGrantObject.FAMILY)) {

                lastMember.setFundNumber(singleRollDTO.getGrantStandard());
                lastMember.setPersonNumber(lastMember.getSaveMembers());
            } else {

                BigDecimal sumFundNumber = BigDecimal.valueOf(singleRollDTO.getGrantStandard())
                        .multiply(BigDecimal.valueOf(lastMember.getSaveMembers())).setScale(2, BigDecimal.ROUND_HALF_UP);
                lastMember.setFundNumber(sumFundNumber.doubleValue());
            }
            lastMember.setId(Constant.getUUID());
            lastMember.setFundPayId(payId);
            results.add(lastMember);
        }
    }


    private SingleFundPayMemberEntity getLastRollMember(String key, Map<String, List<SingleFundPayMemberEntity>> listMap, SingleFundPayMemberEntity sfme) {

        List<SingleFundPayMemberEntity> saveFamilyMembers = listMap.get(key);

        List<SingleFundPayMemberEntity> saveAndMaster = saveFamilyMembers.stream()
                .filter(o -> o.getIsMaster() == 1 && "1".equals(o.getIsSave())).collect(Collectors.toList());

        List<SingleFundPayMemberEntity> saveList = saveFamilyMembers.stream()
                .filter(o -> "1".equals(o.getIsSave())).collect(Collectors.toList());

        Map<String, List<SingleFundPayMemberEntity>> saveListMap = saveList.stream()
                .collect(Collectors.groupingBy(SingleFundPayMemberEntity::getMemberId));
        Set<String> members = saveListMap.keySet();
        SingleFundPayMemberEntity lastMember = null;
        if (saveAndMaster.size() > 0) {
            lastMember = saveAndMaster.get(0);
        } else {
            if (saveList.size() > 0) {
                lastMember = saveList.get(0);
            } else {
                throw new BizException("家庭：" + key + "，数据有误，无在保对象，无法生成名册！");
            }
        }
        BeanUtils.copyProperties(lastMember, sfme);
        sfme.setSaveMembers(members.size());
        sfme.setPersonNumber(1);
        return sfme;
    }
}
